import { BoidStatus, BoidBuff } from "../../config/boid_def";
import { GetBuffType, CONTROL_INCREASE, GrowAttr } from "../../config/play_def";
import { RoleBuff, RoleSkill, CommonBuff, RoleBuffUid } from "../../config/role_def";
import { Control_Listen } from "../../config/ui_def";

cc.Class({
    extends: cc.Component,

    properties: {
        attack_target:{
            visible:false,
            default:null,
        },      // 攻击目标
        _aimSpeed:{
            visible:false,
            default:100,
        },      // 基础瞄准速度
        aimSpeed:{
            get(){
                return (this._aimSpeed + this.getBuff(RoleBuff.Accelerate)) / 100
            }
        },      // 瞄准速度 实际意义攻击速度
        _attackSpeed:{
            visible:false,
            default:400,
        },      // 基础攻击动画速度
        attackSpeed:{
            get(){
                return (this._attackSpeed + this.getBuff(RoleBuff.Accelerate)) / 100
            }
        },      // 攻击动画速度 实际意义为加快多少倍
        attackCharge:0,  // 攻击蓄力
        _damege:{
            visible:false,
            default:10,
        },      // 基础伤害
        damege:{
            get(){
                return this._damege + this.getBuff(RoleBuff.PowerUp)
                // 一秒子弹发射均速度。
            }
        },      // 伤害
        model:sp.Skeleton,      // 模型
        idle_status:false,      // 停止攻击状态
        attack_status:false,    // 是否开启攻击监听
        stop_attack_count:0,    // 沉默状态
        control_dir:cc.v2(0,1), // 目标射击方向
    },
    // 初始化
    initInfo(param,role_info){
        this.buff = []              // Buff  列表
        this.buffDict = {}          // Buff  对应每个Buff效果
        if(param)
            this.info = param           // 信息
        if(role_info){
            this.role_info = role_info
        }
        this._damege = this.info.attack                  // 攻击力
        this._attackSpeed = this.info.attackSpeed           // 攻击速度
        this._aimSpeed = this.info.aimSpeed                 // 瞄准

        this.model = this.node.getChildByName('model').getComponent(sp.Skeleton) // spine 模型
        this.tBase = this.node.getComponent('towerBase')
        if(!this.info){
            he.error("炮塔信息错误，未初始化",param)
            return
        }
        this.attacking = false
        this.initRoleBuff()         // 初始Buff
        this.onSpineListen()        // spine监听
    },
    // 清理节点信息
    clearInfo(){
        this.attacking = false
        this.control_dir = cc.v2(0,1)
        this.attack_status = false              // 取消瞄准
        this.clearRoleBuff()                    // 清楚角色Buff
        this.model.setEventListener(null)       // 取消tag动画监听
        this.model.setCompleteListener(null)    // 取消完成动画监听
    },
    // 初始Buff
    initRoleBuff(){
        let grow_attr = this.role_info.grow.split("#")
        let grow_num = this.role_info.growNum.split("#")
        for(let i = 0;i< grow_num.length;i++){
            grow_num[i] = parseFloat(grow_num[i])
        }

        for(let i = 0; i < grow_attr.length; i++){
            switch(parseInt(grow_attr[i])){
                case GrowAttr.AttackSpeed:
                    let atSpeedUp = {
                        uid: RoleBuffUid.ACCELERATE,
                        key: RoleBuff.Accelerate,
                        value: grow_num[i]
                    }
                    this.addBuff(atSpeedUp)
                break
                case GrowAttr.Crit:
                    let critBuff = {
                        uid: RoleBuffUid.CRIT,
                        key: RoleBuff.Crit,
                        pro: grow_num[i],               // 概率
                        value: 2,               // 倍数
                    }
                    this.addBuff(critBuff)
                break
                case GrowAttr.Hp:
                    let hpMax = {
                        uid: RoleBuffUid.HP_MAX_UP,
                        key: CommonBuff.HP_MAX_UP,
                        value: grow_num[i],
                    }
                    gg.control.addBuff(hpMax)
                break
                case GrowAttr.Power:
                    let atPowerUp = {
                        uid: RoleBuffUid.POWER_UP,
                        key: RoleBuff.PowerUp,
                        value: grow_num[i]
                    }
                    this.addBuff(atPowerUp)
                break
                case GrowAttr.DOT_Buff:
                    let dot4AttackBuff = {
                        uid: RoleBuffUid.DOT4Attack,
                        key: RoleBuff.DOT4Attack,
                        param : 5,
                        value: grow_num[i]
                    }
                    this.addBuff(dot4AttackBuff)
                break
                case GrowAttr.Slow_Buff:
                    let slow4AttackBuff = {
                        uid: RoleBuffUid.Slow4Attack,
                        key: RoleBuff.Slow4Attack,
                        param : 5,
                        value : 5
                    }
                    this.addBuff(slow4AttackBuff)
                break
                case GrowAttr.Repel_Buff:
                    let repelAttackBuff = {
                        uid: RoleBuffUid.Repel4Attack,
                        key: RoleBuff.Repel4Attack,
                        repel : 1000,
                        value : grow_num[i],
                        pro: 30
                    }
                    this.addBuff(repelAttackBuff)
                break
                case GrowAttr.SUPER_Repel_Buff:
                    let SuperRepelAttackBuff = {
                        uid: RoleBuffUid.Repel4Attack,
                        key: RoleBuff.Repel4Attack,
                        repel : 1000,
                        value : grow_num[i],
                        pro: 80
                    }
                    this.addBuff(SuperRepelAttackBuff)
                break
            }
        }
    },
    // 清除Buff
    clearRoleBuff(){
        let grow_attr = this.role_info.grow.split("#")
        let grow_num = this.role_info.growNum.split("#")
        for(let i = 0; i < grow_attr.length; i++){
            switch(parseInt(grow_attr[i])){
                case GrowAttr.Hp:
                    gg.control.delBuff(RoleBuffUid.HP_MAX_UP,GetBuffType.UID)
                    gg.data.updateHpMax()
                break
            }
        }
    },
    // 设置Buff
    /**
    * @description Buff参数
    * @param {Object} param
    * @param {String} info.uid      Buff 唯一标识 可填可不填
    * @param {String} info.key      Buff 类型区分每个Buff对应的效果
    * @param {String} info.value    Buff 具体数值参数
    * @param {String} info.time     Buff 持续时间 -1为永久，参数为帧数
    *
    */
    addBuff(param){
        if(param){
            if(param.uid){
                for(let i = 0;i < this.buff.length;i++){
                    if(this.buff[i].uid == param.uid){
                        this.buff[i] = param
                        return this.updateBuff(param.key)
                    }
                }
                this.buff.push(param)
                return this.updateBuff(param.key)
            }else{
                this.buff.push(param)
                return this.updateBuff(param.key)
            }
        }
    },
    // 获取Buff合集
    getBuff(key){
        if(this.buffDict && (this.buffDict[key] || this.buffDict[key] === 0)){
            return this.buffDict[key]
        }else{
            return this.updateBuff(key)
        }
    },
    // 获得Buff信息
    getBuffInfo(index,type){
        switch(type){
            case GetBuffType.INDEX:
                if(this.buff[index]){
                    return this.buff[index]
                }  
            case GetBuffType.UID:
                for(let i = 0;i < this.buff.length;i++){
                    if(this.buff[i].uid == index){
                        return this.buff[i]
                    }
                }
            break
            case GetBuffType.KEY:
            default:
                for(let i = 0;i < this.buff.length;i++){
                    if(this.buff[i].key == index){
                        return this.buff[i]
                    }
                }
            break
        }
        return null
    },
    // 获取Buff数量
    getBuffList(key){
        let list = []
        for(let i = 0;i < this.buff.length;i++){
            if(this.buff[i].key == key){
                list.push(this.buff[i])
            }
        }
        return list
    },
    // 删除Buff
    delBuff(id,type){
        // type 1 index, type 2 uid , type3 key
        // 索引，唯一，类型
        if(!type){
            type = GetBuffType.INDEX
        }
        switch(type){
            case GetBuffType.INDEX:
                this.buff.splice(id,1)
                break
            case GetBuffType.UID:
                for(let i = 0;i < this.buff.length;i++){
                    let buff = this.buff[i]
                    if(buff.uid && buff.uid == id){
                        this.buff.splice(i,1)
                        break
                    }
                }
                break
            case GetBuffType.KEY:
                for(let i = this.buff.length - 1;i >= 0;i--){
                    let buff = this.buff[i]
                    if(buff.key && buff.key == id){
                        this.buff.splice(i,1)
                    }
                }
                break
        }
        this.updateBuff()
    },
    // 更新Buff
    updateBuff(key){
        if(!this.buff){
            return
        }
        if(gg.data.current == this.node.name){
            gg.eventManager.emit('topbar',Control_Listen.UPDATE_TOWER_BUFF,this.buff)
        }
        if(key){
            let count = 0
            for(let i = 0; i < this.buff.length;i++){
                if(this.buff[i].key == key){
                    count += this.buff[i].value
                }
            }
            this.buffDict[key] = count
            if (key && this.buffDict) {
                if (this.buffDict[key] === undefined) {
                    this.buffDict[key] = 0
                    return 0
                }
                return this.buffDict[key]
            }
            return 0
        }else{
            let buffDict = {}
            for(let key in this.buffDict){
                buffDict[key] = 0
            }
            for(let i = 0; i < this.buff.length;i++){
                if(buffDict[this.buff[i].key]){
                    buffDict[this.buff[i].key] += this.buff[i].value
                }else{
                    buffDict[this.buff[i].key] = this.buff[i].value
                }
            }
            this.buffDict = buffDict
            return 0
        }
    },
    // buff 结束
    overBuff(buff){
        this.updateBuff(buff.key)
        switch(buff.key){
        }
    },
    // 帧检查Buff
    checkBuff(dt){
        if(this.buff && this.buff.length){
            let buffList = []
            for(let i = this.buff.length - 1;i >= 0;i --){
                if(this.buff[i].time > 0){
                    this.buff[i].time -= dt
                }
                if(this.buff[i].time <= 0){
                  buffList.push(this.buff[i])
                  this.buff.splice(i,1)
                }
            }
            if(buffList && buffList.length){
                for(let i = 0;i < buffList.length;i++){
                    this.overBuff(buffList[i])
                }
                if(gg.data.current == this.node.name){
                  gg.eventManager.emit('topbar',Control_Listen.UPDATE_TOWER_BUFF,this.buff)
                }
            }
        }
    },
    // 监听动画
    onSpineListen(){
        this.model.setEventListener((trackEntry, event) => {
            if(event && event.data && event.data.name){
                let tag =  event.data.name
                this.listenAniTag(tag)
            }
        });
        this.model.setCompleteListener((trackEntry) => {
            var animationName = trackEntry.animation ? trackEntry.animation.name : "";
            this.listenAniCom(animationName)
        });
    },
    // 监听动画标签样式
    listenAniTag(tag){
        switch (tag) {
            case 'attack':
                this.attack()
            break
        }
    },
    // 监听动画播完
    listenAniCom(ani){
        let breakS = ani.indexOf('_')
        let tag = ani
        if(breakS >= 0){
            tag = ani.substring(breakS + 1,ani.length)
        }
        switch (tag) {
            case 'attack':
                if(this.attack_target && this.attack_target.canAttack()){
                    this.model.timeScale = this.aimSpeed
                    this.tBase.changeAni(this.info.pre + '_attack_before')
                }else{
                    this.model.timeScale = 1
                    this.tBase.changeAni(this.info.pre + "_stand_by")
                }
                this.attacking = false
            break
        }
    },
    // 攻击动作
    attack(){     
        // 攻击声音
        if(this.info && this.info.attackVoice){
            he.voice.playEffect(`${this.info.attackVoice}`,`bullet`)
        }
    },
    // 查找对应目标
    findTarget(){
        let s = -1
        let near = -1
        let towerPos = this.node.convertToWorldSpaceAR(cc.Vec2.ZERO)
        for(let i = 0; i < gg.boidsManager.boids_list.length; i++){
            if(!gg.boidsManager.boids_list[i].canAttack()){
                continue
            }
            if(gg.boidsManager.boids_list[i].fly && !this.attack_fly){
                continue
            }
            if(gg.boidsManager.boids_list[i].getBuff(BoidBuff.Hide)){
                continue
            }
            if(!gg.boidsManager.boids_list[i].collision.enabled){
                continue
            }

            let boidPos = gg.boidsManager.boids_list[i].node.convertToWorldSpaceAR(cc.Vec2.ZERO)
            let dis = towerPos.sub(boidPos).mag()

            if(near < 0){
                near = dis
                s = i
            }else if(near > dis){
                near = dis
                s = i
            }
        }
        if(near >= 0 && gg.boidsManager.boids_list[s] && gg.boidsManager.boids_list[s].canAttack()){
            if(gg.boidsManager.boids_list[s].fly && !this.attack_fly){
                return null
            }
            if(s >= 0){
                return gg.boidsManager.boids_list[s]
            }
        }
        return null

    },
    // 闲置动画 强行覆盖
    IdelAction(force){
        if(!this.idle_status || force){
            this.idle_status = true
            this.model.timeScale = 1
            this.model.setAnimation(0,this.info.pre + '_stand_by',true)
            // if(this.stop_attack_count > 0){
            // //   this.tBase.changeDriverAni('driver_stun')
            // }else{
            // //   this.tBase.changeDriverAni('driver_stand')
            // }
            this.tBase.lastAni = this.info.pre + '_stand_by'
            this.attacking = false
        }
    },
    // 绑定目标动画
    bindAction(){
    //   this.tBase.changeDriverAni('driver_operation')
    },
    // 炮塔口径转向
    turnDir(pos){
        let apos    // 目标位置
        if(pos){
            apos = pos
        }else{
            if(this.attack_target.getBuff(BoidBuff.Hide)){
                this.attack_target = null
                return 0
            }
            apos = this.attack_target.node.convertToWorldSpaceAR(cc.Vec2.ZERO)
        }
        let tpos = this.node.convertToWorldSpaceAR(cc.Vec2.ZERO)
        let dir = apos.sub(tpos)
        var angle = dir.signAngle(cc.v2(1,0));
        var degree = angle / Math.PI * 180 + 90;
        while (Math.abs(degree) > 360) {
            if(degree < 0){
                degree += 360
            }else{
                degree -= 360
            }
        }
        if(degree < 0){
            degree = 360 + degree
        }
        
        if(degree > 90 && degree < 180){
            degree = 90
            this.control_dir = cc.v2(1,0)

        }else if(degree < 270 && degree > 180){
            degree = 270   
            this.control_dir = cc.v2(-1,0)
        }else{
            if(this.tBase.controling){
                this.control_dir = dir.normalizeSelf()
            }
        }
        return degree
    },
    // 瞄准监听开启 类似boid的 move
    changeStatus(status){
        this.attack_status = status
        if(!this.attack_status){
            this.attack_target = null
            this.IdelAction()
        }
    },
    // 摇头检测
    checkTurn(dt){
        if(this.tBase.controling){
            return
        }
        if(this.attack_status){
            if(gg.boidsManager.getLiveBool() && this.stop_attack_count <= 0){
                if(this.idle_status){
                    this.idle_status = false
                }
                if(!this.attack_target || !this.attack_target.canAttack() || !this.attack_target.node.active || this.attack_target.getBuff(BoidBuff.Hide)){
                    this.attack_target = this.findTarget()
                    if(!this.attack_target){
                        this.IdelAction()
                    }
                }else{
                    this.turnDir()
                }
            }else{
                if(this.stop_attack_count > 0){
                    this.stop_attack_count -= dt
                }
                this.IdelAction()
            }
        }
    },
    // 检测攻击进度
    checkAtkPro(dt){
        if(this.tBase.controling){
            if(!gg.control.attacking){
                return
            }
            if(this.attacking){
                return
            }
            this.idle_status = false
            this.model.timeScale = this.aimSpeed * CONTROL_INCREASE
            this.tBase.changeAni(this.info.pre + '_attack_before')
            if(this.attackCharge < 1/this.aimSpeed){
                this.attackCharge += dt * CONTROL_INCREASE
            }else{
                this.attackCharge = 0
                this.model.timeScale = this.attackSpeed
                this.tBase.changeAni(this.info.pre + '_attack')  
                this.attacking = true
            }
            return
        }
        if(this.idle_status){
            return
        }
        if(this.attacking){
            return
        }
        this.tBase.changeAni(this.info.pre + '_attack_before')
        if(this.model.timeScale != this.aimSpeed){
            this.model.timeScale = this.aimSpeed 
        }
        if(this.attackCharge < 1/this.aimSpeed){
            this.attackCharge += dt
        }else{
            if(!this.attacking && this.attack_target && this.attack_target.canAttack()){
                this.attackCharge = 0
                this.model.timeScale = this.attackSpeed
                this.tBase.changeAni(this.info.pre + '_attack')  
                this.attacking = true
            }
        }
    },
    // 获取世界坐标
    getWorldPos(){
        let worldPos = this.node.convertToWorldSpaceAR(cc.Vec2.ZERO)
        return cc.v2(parseInt(worldPos.x),parseInt(worldPos.y))
    },
    // 子弹出口位置
    getBulletWorldPos(){
        // let worldPos = this.model.node.convertToWorldSpaceAR(cc.Vec2.ZERO)
        let worldPos = this.tBase.model_node.convertToWorldSpaceAR(cc.Vec2.ZERO)
        return cc.v2(parseInt(worldPos.x),parseInt(worldPos.y))
    },
    // 子弹方向
    v2Target(){
        if(this.tBase.controling){
            return this.control_dir
        }
        if(this.attack_target && this.attack_target.canAttack()){
            let apos = this.attack_target.node.convertToWorldSpaceAR(cc.Vec2.ZERO)
            let tpos = this.node.convertToWorldSpaceAR(cc.Vec2.ZERO)
            return apos.sub(tpos).normalizeSelf()
        }else{
            return cc.Vec2.ZERO
        }
    },
    // 子弹特效
    getRoleBulletSkill(bullet){
        // 位置#角色_等级#装备_等级
        bullet.attack_from = `${this.node.name}#${this.role_info.roleId}_${this.role_info.level}#${this.info.equip}_${this.info.level}`
        bullet.effect = []
        let crit_list = this.getBuffList(RoleBuff.Crit)
        if(crit_list && crit_list.length){
            for(let i = 0;i < crit_list.length;i++){
                bullet.effect.push({
                    key: RoleSkill.Crit,
                    pro: crit_list[i].pro,          // 概率
                    mul: crit_list[i].value       // 倍数
                })
            }
        }
        // 到时候优化成switch
        let dot_list = this.getBuffList(RoleBuff.DOT4Attack)
        if(dot_list && dot_list.length){
            for(let i = 0;i < dot_list.length;i++){
                bullet.effect.push({
                    key: RoleSkill.DOT,
                    uid: RoleBuffUid.DOT4Attack,
                    value: dot_list[i].value,               // 参数值 伤害值
                    max: 9,                                 // 最大叠层
                    time: 1,                                // 多长时间发动一次
                    overtime: dot_list[i].param,            // 持续时间 
                })
            }
        }
        let slow_list = this.getBuffList(RoleBuff.Slow4Attack)
        if(slow_list && slow_list.length){
            for(let i = 0;i < slow_list.length;i++){
                bullet.effect.push({
                    key: RoleSkill.BoidSLow,
                    uid: RoleBuffUid.Slow4Attack,
                    value: slow_list[i].value,               // 参数值 伤害值
                    time: slow_list[i].param,                // 多长时间发动一次
                })
            }
        }
        let repel_list = this.getBuffList(RoleBuff.Repel4Attack)
        if(repel_list && repel_list.length){
            for(let i = 0;i < repel_list.length;i++){
                let randomRes = 100 * Math.random()
                if(randomRes < repel_list[i].pro){
                    bullet.effect.push({
                        key: RoleSkill.Repel,
                        uid: RoleBuffUid.Repel4Attack,
                        value: repel_list[i].value,                // 参数值 伤害值
                        repel: repel_list[i].repel,                // 多长时间发动一次
                    })
                }
            }
        }
        // let skill_type = parseInt(this.roleInfo.paSkill)
        // let skill_param = this.roleInfo.paParam.split("/")
        //     // 吸收投掷物体
        //     // 群体攻击力增加
        //     // 群体攻速增加
        //     // 群体减速
        //     // 群体毒液
        //     // 召唤道具
        //     // 增加点击量
        //     switch(skill_type){
        //         case RoleSkill.BoidSLow:
        //             bullet.effect.push({
        //                 key: RoleSkill.BoidSLow,
        //                 uid: parseInt(skill_param[0]),      // 唯一id 图标之类
        //                 value: parseInt(skill_param[1]),    // 参数值 会减少多少速度
        //                 max: parseInt(skill_param[2]),      // 单减速最大值
        //                 time: parseInt(skill_param[3])      // 持续时间
        //             })
        //         break
        //         case RoleSkill.Repel:
        //             let repelRes = parseInt(skill_param[0])
        //             let repelRandom = Math.random() * 100
        //             if(repelRandom < repelRes){
        //                 bullet.effect.push(
        //                     {
        //                         key: RoleSkill.Repel,
        //                         value:parseInt(skill_param[1]),  // 一共
        //                         limit:parseInt(skill_param[2]),  // 每秒
        //                     }
        //                 )
        //             }
        //         break
        //         case RoleSkill.DOT:
        //             bullet.effect.push({
        //                 key: RoleSkill.DOT,
        //                 uid: parseInt(skill_param[0]),          // 唯一id 图标之类
        //                 value: parseInt(skill_param[1]),        // 参数值 伤害值
        //                 max: parseInt(skill_param[2]),          // 最大叠层
        //                 time: parseInt(skill_param[3]),         // 多长时间发动一次
        //                 overtime: parseInt(skill_param[4]),     // 持续时间 
        //                 ani:skill_param[5],                     // Buff动画
        //             })
        //         break 
        //         case RoleSkill.Crit:
        //             bullet.effect.push({
        //                 key: RoleSkill.Crit,
        //                 pro: parseInt(skill_param[0]),          // 概率
        //                 mul: parseFloat(skill_param[1]),        // 倍数
        //             })
        //         break
        //         case RoleSkill.AOE:
        //             bullet.effect.push({
        //                 key: RoleSkill.AOE,
        //                 pro: parseInt(skill_param[0]),          // 概率
        //                 range: parseInt(skill_param[1]),                   // 范围 是以中心下坐标为原点计算的 135是单位碰撞大小 所以要比单位面积高 150
        //                 value: parseInt(skill_param[2]),                   // 上升幅度百分比
        //                 ani: skill_param[3]
        //             })
        //         break
        //         case RoleSkill.Splash:
        //             bullet.effect.push({
        //                 key: RoleSkill.Splash, 
        //                 pro: parseInt(skill_param[0]),                     // 概率
        //                 range: parseInt(skill_param[1]),                   // 范围 与上面类似但是 是顶点作为范围
        //                 value: parseInt(skill_param[2]),                   // 上升幅度百分比
        //                 ani: skill_param[3],
        //             })
        //         break
        //         case RoleSkill.Stun:
        //             bullet.effect.push({
        //                 key: RoleSkill.Stun, 
        //                 pro: parseInt(skill_param[0]),                     // 概率
        //                 value: parseInt(skill_param[1]),                   // 时间
        //             })
        //         break
        //     }
            
        //     // 其他技能检测
            
        // }
        return bullet
    },
    // 检测攻击速度
    update (dt) {
        if(this.attack_status && gg.data.status && !gg.data.pause){
            this.checkBuff(dt)
            this.checkTurn(dt)
            this.checkAtkPro(dt)
        }
    },
});

